package com.twu.biblioteca.service;

import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.twu.biblioteca.Library.Book;

import java.security.InvalidParameterException;
import java.util.List;

import static com.google.common.collect.FluentIterable.from;

public class BookService {

    private List<Book> books;

    public BookService(List<Book> books) {
        this.books = books;
    }

    public List<Book> getAllBooks() {
        return books;
    }

    public List<Book> getAllAvailableBooks() {
        return from(books).filter(new Predicate<Book>() {
            @Override
            public boolean apply(Book book) {
                return book.isAvailable();
            }
        }).toList();
    }

    public List<String> getBookNames(List<Book> books) {
        return from(books).transform(new Function<Book, String>() {
            @Override
            public String apply(Book book) {
                return book.getName();
            }
        }).toList();
    }

    public void checkOutBook(String bookName, String userName) throws InvalidParameterException{
        Book book = findBookByName(bookName);
        book.setAvailable(false);
        book.setBorrower(userName);
    }

    public Book findBookByName(final String bookName) {
        Book book;
        try {
             book = from(getAllAvailableBooks()).firstMatch(new Predicate<Book>() {
                @Override
                public boolean apply(Book book) {
                    return bookName.equals(book.getName());
                }
            }).get();

        } catch (Exception e) {
            throw new InvalidParameterException();
        }
        return book;
    }


    public void returnBook(String bookName, String userName) {
        Book book = findBorrowedBook(bookName, userName);
        book.setAvailable(true);
        book.setBorrower(null);
    }

    public Book findBorrowedBook(final String bookName, final String userName) {
        Book book;
        try {
            book = from(books).firstMatch(new Predicate<Book>() {
                @Override
                public boolean apply(Book book) {
                    return bookName.equals(book.getName()) && userName.equals(book.getBorrower());
                }
            }).get();

        } catch (Exception e) {
            throw new InvalidParameterException();
        }
        return book;
    }
}
